package com.cskaoyan.wordmemorize.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cskaoyan.wordmemorize.common.constant.ResultCodeEnum;
import com.cskaoyan.wordmemorize.common.exception.BusinessException;
import com.cskaoyan.wordmemorize.converter.VocBookConverter;
import com.cskaoyan.wordmemorize.dao.entity.VocBookDO;
import com.cskaoyan.wordmemorize.dao.entity.VocCategoryDO;
import com.cskaoyan.wordmemorize.dao.entity.VocChapBookDO;
import com.cskaoyan.wordmemorize.dao.entity.VocChapterDO;
import com.cskaoyan.wordmemorize.dao.mapper.VocBookMapper;
import com.cskaoyan.wordmemorize.dao.mapper.VocCategoryMapper;
import com.cskaoyan.wordmemorize.dao.mapper.VocChapBookMapper;
import com.cskaoyan.wordmemorize.dao.mapper.VocChapterMapper;
import com.cskaoyan.wordmemorize.dto.admin.DeleteBookOperateDTO;
import com.cskaoyan.wordmemorize.dto.admin.PageDTO;
import com.cskaoyan.wordmemorize.dto.admin.VocBookDTO;
import com.cskaoyan.wordmemorize.request.BatchDeleteCommand;
import com.cskaoyan.wordmemorize.request.VocBookCommand;
import com.cskaoyan.wordmemorize.request.VocBookPageRequest;
import com.cskaoyan.wordmemorize.service.VocBookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class VocBookServiceImpl extends ServiceImpl<VocBookMapper, VocBookDO> implements VocBookService{
    @Autowired
    VocBookConverter vocBookConverter;
    @Autowired
    VocCategoryMapper vocCategoryMapper;
    @Autowired
    VocChapBookMapper vocChapBookMapper;
    @Autowired
    VocChapterMapper vocChapterMapper;

    /**
     * 新增书籍
     * @param command
     * @return
     */
    @Override
    public Long addVocBook(VocBookCommand command) {
        VocBookDO vocBookDO = vocBookConverter.vocBookCommand2VocBookDO(command);
        boolean save = save(vocBookDO);
        if (!save) {
            //如果没有成功直接抛出异常，不再交由controller判断
            throw new BusinessException(ResultCodeEnum.FAIL);
        }
        // 在书籍类名表中更新book_count
        LambdaUpdateWrapper<VocCategoryDO> vocCategoryDOLambdaUpdateWrapper = new LambdaUpdateWrapper<VocCategoryDO>()
                .eq(VocCategoryDO::getId, vocBookDO.getBcId())
                .setSql("book_count = book_count + 1");
        vocCategoryMapper.update(vocCategoryDOLambdaUpdateWrapper);
        Long id = vocBookDO.getId();
        return id;
    }

    @Override
    public void updateVocBook(VocBookCommand command) {
        VocBookDO vocBookDO = vocBookConverter.vocBookCommand2VocBookDO(command);
        LambdaQueryWrapper<VocBookDO> eq = new LambdaQueryWrapper<VocBookDO>()
                .eq(VocBookDO::getId, command.getId());
        boolean update = update(vocBookDO, eq);

//        boolean b = updateById(vocBookDO);
        if (!update) {
            throw new BusinessException(ResultCodeEnum.FAIL);
        }
    }

    /**
     * 分页查询请求有多种情况:
     * 查询类目下的书籍，
     * 查询类目下包含关键字的书籍,
     * 两个条件都符合的书籍
     *
     * @param pageQuery
     * @return
     */
    @Override
    public PageDTO<VocBookDTO> getBookPage( VocBookPageRequest pageQuery) {
        // 分情况查询
        String categoryId = pageQuery.getCategoryId();
        String keyword = pageQuery.getKeyword();
        // 构建分页查询，页对象
        Integer pageNum = pageQuery.getPageNum() == null?0:pageQuery.getPageNum();
        Integer count = pageQuery.getCount()== null?1000:pageQuery.getCount();
        Page<VocBookDO> page = new Page<>(pageNum, count);
        LambdaQueryWrapper<VocBookDO> vocBookDOLambdaQueryWrapper = new LambdaQueryWrapper<>();
        // 查询类目下的书籍 添加类目录id条件
        if (categoryId != null) {
            vocBookDOLambdaQueryWrapper.eq(VocBookDO::getBcId, categoryId);
        }
        // 查询类目录下关键字的书籍 添加关键字条件
        if (keyword != null && !keyword.equals("")) {
            vocBookDOLambdaQueryWrapper
                    .like(VocBookDO::getName, keyword);
        }
        List<VocBookDO> vocBookDOList = list(page, vocBookDOLambdaQueryWrapper);
        long size = page.getTotal();
        PageDTO<VocBookDTO> vocBookDTOPageDTO = vocBookConverter.vocBookList2Page(vocBookDOList, size);
        return vocBookDTOPageDTO;
    }

    @Override
    public DeleteBookOperateDTO deleteVocBook(Long bookId) {
        // 删除前先封装数据到VocBookDO对象，以便返回
        VocBookDO vocBookDO = new VocBookDO();
        vocBookDO.setId(bookId);
        VocBookDO vocBookDOById = getById(bookId);
        if(vocBookDOById == null) {
            return null;
//            throw new RuntimeException("要删除的书籍不存在");
        }
        vocBookDO.setBcId(vocBookDOById.getBcId());
        vocBookDO.setName(vocBookDOById.getName());
        vocBookDO.setBcName(vocBookDOById.getBcName());

        boolean b = removeById(vocBookDO);
        if (!b) {
            // 未进行删除操作
            return vocBookConverter.vocBookDO2DeleteBookDTO(vocBookDO);
        }
        // 更新book_category表中的相关信息
        LambdaUpdateWrapper<VocCategoryDO> vocCategoryDOLambdaUpdateWrapper = new LambdaUpdateWrapper<VocCategoryDO>()
                .eq(VocCategoryDO::getId, vocBookDO.getBcId())
                .setSql("book_count = book_count - 1");
        vocCategoryMapper.update(vocCategoryDOLambdaUpdateWrapper);
        // 更新voc_chapter表中的相关信息
        LambdaQueryWrapper<VocChapterDO> vocChapterWrapper = new LambdaQueryWrapper<VocChapterDO>()
                .eq(VocChapterDO::getBookId, vocBookDO.getId());
        int deleteVocChapter = vocChapterMapper.delete(vocChapterWrapper);
        // voc_chap_book表中的相关信息
        LambdaQueryWrapper<VocChapBookDO> vocChapBookDOWrapper = new LambdaQueryWrapper<VocChapBookDO>()
                .eq(VocChapBookDO::getBookId, vocBookDO.getId());
        int deleteVocChapBook = vocChapBookMapper.delete(vocChapBookDOWrapper);

        DeleteBookOperateDTO deleteBookOperateDTO = vocBookConverter.vocBookDO2DeleteBookDTO(vocBookDO);
        return deleteBookOperateDTO;
    }

    /**
     * 批量删除书籍要考虑删除后其他表（类目录）中该书籍的情况
     *
     * @param command
     * @return
     */
    @Override
    public List<DeleteBookOperateDTO> deleteVocBooks(BatchDeleteCommand command) {
        List<String> ids = command.getIds();
        if(ids == null){
            return null;
        }
        List<DeleteBookOperateDTO> list = ids.stream()
                .map(id -> deleteVocBook(Long.valueOf(id)))
                .toList();
        return list;
    }
}
